home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.004 / FGUSER10.TXT < prev    next >
Text File  |  1995-05-29  |  18KB  |  448 lines

  1.                                 Classic Menus
  2.  
  3.                                      "If gold rust what shall iren do?"
  4.                                                  Chaucer 1340-1400
  5.  
  6. Introduction
  7.  
  8.           A classic menu is a menu displayed in a window (as shown in
  9.      figure 10.1 below). In applications that don't use a desktop (like
  10.      Quicken) the classic menu often forms the main screen of the
  11.      program. The GOLDMENU unit provides pop-up menus with the following
  12.      features:
  13.  
  14.          - Automatic prefixing of options with numbers, letters or
  15.            function keys.
  16.          - Support for disabled options.
  17.          - Automatic menu placement with multiple column support.
  18.          - Full mouse support.
  19.  
  20.  
  21.      Figure 10.1
  22.      A Classic Menu
  23.  
  24.  
  25. Basic Concepts
  26.  
  27.      GOLDMENU defines the MenuRecord record as follows:
  28.  
  29.           MenuRecord = record
  30.              Heading1     : string[MenuStrLength];
  31.              Heading2     : string[MenuStrLength];
  32.              Topic      : array[1..MaxChoices] of string[MenuStrLength];
  33.              TotalPicks   : integer;
  34.              PicksPerLine : byte;
  35.              AddPrefix    : byte;
  36.              TopLeftXY    : array[1..2] of byte;
  37.              Boxtype      : byte;
  38.              Colors       : array[1..5] of byte;
  39.              Margins      : byte;
  40.              AllowEsc     : boolean;
  41.              Hook         : MenuHook;
  42.              HindHook     : MenuHindHook;
  43.           end; {MenuRecord}
  44.  
  45.           A menu record defines all the properties of the menu, i.e. the
  46.      headings, the colors, the position, the menu items, etc. The basic
  47.      approach to displaying a menu is to declare a variable of type
  48.      MenuRecord, update the record variable with the menu items,
  49.      headings etc., and call DisplayMenu to instruct Gold to display the
  50.      menu and return when the user has made a selection.
  51.  
  52.           Listed below is an extract from the demo program DEMMEN1.PAS
  53.      which illustrates this basic approach:
  54.  
  55.           var
  56.             MainMenu: MenuRecord;
  57.             Choice,Ecode: integer;
  58.  
  59.  
  60.           procedure SetMenu;
  61.           {}
  62.           begin
  63.              MenuSet(MainMenu);
  64.              with MainMenu do
  65.              begin
  66.                 Heading1     := 'TechnoJock''s Turbo Toolkit';
  67.                 Heading2     := 'Gold!';
  68.                 Topic[1]     := 'Unit Descriptions';
  69.                 Topic[2]     := '!Unit Demos';
  70.                 Topic[3]     := 'Self-Running Demo';
  71.                 Topic[4]     := 'How to register';
  72.                 Topic[5]     := 'About GOLD';
  73.                 Topic[6]     := '';
  74.                 Topic[7]     := 'Exit Demo';
  75.                 TotalPicks   := 7;
  76.                 Boxtype      := 5;
  77.                 AddPrefix    := 3;
  78.                 PicksPerLine := 1;
  79.                 AllowEsc     := false;
  80.              end;
  81.           end; { SetMenu }
  82.  
  83.           begin
  84.              ...
  85.              SetMenu;
  86.              DisplayMenu(MainMenu,false,Choice,ECode);
  87.              ...
  88.           end.
  89.  
  90. Use MenuSet First!
  91.  
  92.           Important Note: Always, always, call the MenuSet function to
  93.      initialize a menu record before assigning values to the various
  94.      menu record components. MenuSet initializes all the menu record
  95.      elements to suitable default values.
  96.  
  97. Managing the MenuRecord
  98.  
  99.      Listed below is a description of the main MenuRecord fields:
  100.  
  101.           Heading1 - The heading at the top of the menu. Set the string
  102.                to null (the default) if you don't want a heading.
  103.  
  104.           Heading2 - The second heading at the top of the menu. Set the
  105.                string to null (the default) if you don't want a heading.
  106.  
  107.           Topic - An array of the actual menu items that will be
  108.                displayed in the menu. Start with the first element,
  109.                assign menu items strings to each element of the array
  110.                until you have fully defined the menu items, e.g.
  111.  
  112.                 Topic[1]     := 'Unit Descriptions';
  113.                 Topic[2]     := '-Unit Demos';
  114.                 Topic[3]     := 'Self-Running Demo';
  115.                 Topic[4]     := 'How to register';
  116.                 Topic[5]     := 'About GOLD';
  117.                 Topic[6]     := '';
  118.                 Topic[7]     := 'Exit Demo';
  119.  
  120.           TotalPicks - The total number of items in the menu. In the
  121.                above example, the value would be 7.
  122.  
  123.           PicksPerLine - Identifies how many items will be displayed on
  124.                each line in the menu. Gold automatically adjusts this
  125.                setting if the text is too long to fit on the screen.
  126.  
  127.           AddPrefix - Gold can automatically prefix the menu items with
  128.                numbers, letters or function keys. By default, the prefix
  129.                is zero which indicates that no prefix should be used.
  130.                The other valid settings are 1, 2, 3 and 4 as follows:
  131.  
  132.                1 All menu options are prefixed with a single digit
  133.                  number. If TotalPicks exceeds 9, an alpha prefix will
  134.                  be used instead.
  135.                2 All menu options are prefixed with a letter, starting
  136.                  with A. If TotalPicks exceeds 26, the prefix is
  137.                  ignored.
  138.                3 All menu options are prefixed with a function key,
  139.                  beginning with F1. If total picks exceeds 10, the Gold
  140.                  will prefix with alphas instead.
  141.                4 The first capital letter in each item is highlighted
  142.                  and the user can select the item by pressing the
  143.                  highlighted letter.
  144.  
  145.           TopLeftXY - A two byte array which identifies the X and Y
  146.               coordinate for the top left corner of the menu -- Gold
  147.               automatically determines the overall dimensions of the
  148.               menu based upon the length of headings and items. If you
  149.               specify coordinates too close to a screen edge, Gold
  150.               automatically adjusts the menu position so that it is
  151.               fully visible. When the X coordinate is set to 0, the menu
  152.               is centered horizontally on the display. Similarly, a Y
  153.               coordinate 0 will center the menu vertically. For example,
  154.               if you want the menu to be displayed in the center of the
  155.               screen starting on the seventh line, the declaration would
  156.               be:
  157.  
  158.                MainMenu.TopLeftXY[1] := 0;
  159.                MainMenu.TopLeftXY[2] := 7;
  160.  
  161.           BoxType - Indicates the window style, and should have a value
  162.                in the range 0 to 2 or 5, as follows:
  163.  
  164.                0 No Border
  165.                1 Single Line Border
  166.                2 Double Line Border
  167.                5 Quicken-style menu
  168.  
  169.           Colors - A five byte array which defines the menu display
  170.                colors. Refer to the section Customizing Menu Colors
  171.                (later) for more information.
  172.  
  173.           Margins - The number of spaces separating the menu border and
  174.                the picks. Typical values range from 1 to 5.
  175.  
  176.           AllowEsc - A boolean variable which controls whether the Esc
  177.                key is operative, i.e. whether or not the user can escape
  178.                from the menu. When this field is set to FALSE, the
  179.                escape key is ignored, otherwise the menu session
  180.                finishes and the Retcode is set to 1.
  181.  
  182. A Few Tips and Tricks
  183.  
  184.           If a menu topic begins with the exclamation character (!), the
  185.      menu item will be inactive, i.e. grayed out.
  186.  
  187.           If you want a blank line between two specific items, specify
  188.      an item in between the two using a null string -- this approach is
  189.      used in DEMMEN1.PAS on element 6.
  190.  
  191.           Don't forget that the menu will be automatically centered if
  192.      the TopLeftXY[1] and TopLeftXY[2] elements are set to zero.
  193.  
  194.           By default, Gold supports a maximum of 30 items in a menu. If
  195.      you need more than 30, just assign a higher value to the GOLDMENU
  196.      constant MaxChoices.
  197.  
  198. Displaying the Menu
  199.  
  200.           Having called MenuSet and configured the menu record, use
  201.      DisplayMenu (defined below) to display the menu.
  202.  
  203.      DisplayMenu(MenuDef: MenuRecord; Window:Boolean;
  204.                            var Choice,Errorcode: integer);
  205.  
  206.           Displays a classic menu. MenuDef is the menu record defining
  207.      the menu content. Set Window to true if you want the menu to be
  208.      removed when a selection is made, or false if you want the menu to
  209.      remain visible. The Choice variable is updated with the user's
  210.      selection. Error codes are returned in the ErrorCode variable.
  211.  
  212. Controlling the Default Menu Selection
  213.  
  214.           The third parameter passed to DisplayMenu is a variable
  215.      integer parameter which is updated with the selection made by the
  216.      user, e.g. it will have a value of 7 if the user selects the
  217.      seventh menu option.
  218.  
  219.           This variable also controls which menu item is highlighted
  220.      when the menu is first displayed. Be sure to assign an appropriate
  221.      value to the Choice variable before calling DisplayMenu.
  222.  
  223. Checking the Return Code
  224.  
  225.           If the user is allowed to escape (by setting the menu record
  226.      field AllowEsc to TRUE), you will need to test the value of the
  227.      ErrorCode parameter before launching the appropriate menu
  228.      selection. If the user escaped from the menu, ErrorCode will be set
  229.      to 1, otherwise it will have a value of zero.
  230.  
  231. Customizing the Menu Colors
  232.  
  233.           The default menu colors assigned to each individual menu can
  234.      be set using the GoldSetColor procedure, assigning attributes to
  235.      the following TINT elements:
  236.  
  237.           MenuHiHot
  238.           MenuHi
  239.           MenuNormHot
  240.           MenuNorm
  241.           MenuBorder
  242.  
  243.  
  244.           The following code is an extract from DEMMEN2.PAS which
  245.      assigns custom colors to the menu defaults:
  246.  
  247.           procedure CustomizeColors;
  248.           {}
  249.           begin
  250.              GoldSetColor(MenuHiHot,YellowOnGreen);
  251.              GoldSetColor(MenuHi,BlackonGreen);
  252.              GoldSetColor(MenuNormHot,YellowOnMagenta);
  253.              GoldSetColor(MenuNorm,WhiteOnMagenta);
  254.              GoldSetColor(MenuOff,LightgrayonMagenta);
  255.              GoldSetColor(MenuBorder,YellowOnMagenta);
  256.           end; { CustomizeColors }
  257.  
  258.           The GoldSetColor procedure should be called prior to
  259.      initializing the menu record with MenuSet.
  260.  
  261.           The technique just described controls the default colors for
  262.      all menus. You can change the colors for an individual menu by
  263.      modifying the values of the menu record's Colors array, after
  264.      initializing the record with MenuSet. Each of the five elements of
  265.      the array control the display colors of the menu as follows:
  266.  
  267.           Colors[1]  The highlighted item's prefix.
  268.           Colors[2]  The text of the highlighted item.
  269.           Colors[3]  The menu headings and the standard items prefix.
  270.           Colors[4]  The text of the standard items.
  271.           Colors[5]  The menu border color.
  272.  
  273.           The color of non-selectable items (i.e. items which start with
  274.      the minus character) can only be altered by using the GoldSetColor
  275.      method (described above) using the MenuOff element.
  276.  
  277. Using Menu Hooks
  278.  
  279.           Classic menus support two types of hooks: hind hooks and
  280.      character hooks:
  281.  
  282. Using Hind Hooks
  283.  
  284.           The hind hook is called once when the menu is first displayed,
  285.      and every time a keystroke or mouse click is processed by the menu.
  286.      A hind hook is ideal for displaying a long description for the
  287.      highlighted topic.
  288.  
  289.           For a procedure to be eligible as a pop-up menu hind hook it
  290.      must adhere to the following rules:
  291.  
  292.           The procedure must be declared as a far procedure at the root
  293.           level. Refer to the section Understanding Hooks in Chapter 3
  294.           for further information.
  295.  
  296.           The procedure must be declared with two passed parameters. The
  297.           first integer parameter indicates the active item. The second
  298.           parameter must be a variable of type integer; if this variable
  299.           is assigned a non-zero value, the menu will automatically
  300.           terminate, and the Errorcode (passed to DisplayMenu) will be
  301.           assigned the value.
  302.  
  303.      The following procedure declaration follows these rules:
  304.  
  305.           {$F+}
  306.           procedure LongDesc(Choice:integer; var Ecode:integer);
  307.           {Displays a long description for the highlighted topic}
  308.           var Msg: StrScreen;
  309.           begin
  310.              ClearLine(24,WhiteOnBlue);
  311.              case Choice of
  312.                1: Msg := 'Provides descriptions of each unit';
  313.                2: Msg := 'Demos showing the power of each unit';
  314.                3: Msg := 'Launches into the self-running demo';
  315.                4: Msg := 'Explains how you can register Gold';
  316.                5: Msg := 'Displays program information';
  317.                7: Msg := 'Stops the program';
  318.              end;
  319.              WriteCenter(24,UseTint,Msg);
  320.           end; { LongDesc }
  321.           {$F-}
  322.  
  323.           Having written a procedure following the rules, the menu
  324.      record field HindHook should be set to the procedure, e.g.
  325.  
  326.           MainMenu.HindHook := LongDesc;
  327.  
  328.      The demo program DEMMEN3.PAS illustrates how to use a hind hook.
  329.  
  330. Using Character Hooks
  331.  
  332.           A classic menu character hook is a procedure which is called
  333.      every time a key is pressed. The hooked procedure is called before
  334.      the key is processed, i.e. before the character is handled by
  335.      DisplayMenu. The hook is particularly useful for trapping special
  336.      keys like F1 for help, or Alt-X to exit.
  337.  
  338.           For a procedure to be eligible as a pop-up menu character hook
  339.      it must adhere to the following rules:
  340.  
  341.           The procedure must be declared as a far procedure at the root
  342.           level. Refer to the section Understanding Hooks in Chapter 3
  343.           for further information.
  344.  
  345.           The procedure must be declared with one variable parameter of
  346.           type word, and variable of type integer, and a variable
  347.           parameter of type integer. The first parameter indicates which
  348.           key was pressed. the second parameter indicates which pick is
  349.           highlighted. If this variable is assigned a non-zero value,
  350.           the menu will automatically terminate, and the Errorcode
  351.           (passed to DisplayMenu) will be assigned the value.
  352.  
  353.  
  354.      The following procedure declaration follows these rules:
  355.  
  356.           {$F+}
  357.           procedure CheckForKeys(var Key:word; Choice:integer;
  358.                                                  var Ecode:integer);
  359.           {Checks for F1 or Alt-X}
  360.           begin
  361.              if Key = 315 then
  362.                 .....
  363.           end; { CheckForkeys }
  364.           {$F-}
  365.  
  366.           Having written a procedure following the rules, the menu
  367.      record field Hook should be set to the procedure, e.g.
  368.  
  369.           MainMenu.Hook := CheckForkeys;
  370.  
  371.           The demo program DEMMEN4.PAS illustrates how to use a pop-up
  372.      menu character hook.
  373.  
  374. Structuring a Menu-Driven Program
  375.  
  376.           If you are writing an application which uses a Gold classic
  377.      menu as the main menu, read on.
  378.  
  379. Using a Repeat-Until Loop
  380.  
  381.           DisplayMenu displays a menu and returns the value selected by
  382.      the user. If you want an application to always return to the main
  383.      menu after completing a task selected by the user, the DisplayMenu
  384.      statement must be placed in some form of loop.
  385.  
  386.           Listed below is an extract from DEMMEN1.PAS which loops
  387.      continuously back to the main menu:
  388.  
  389.           SetScreen;
  390.           SetMenu;
  391.           MouseShow(true);
  392.           Choice := 5;
  393.           repeat
  394.              DisplayMenu(MainMenu,false,Choice,ECode);
  395.              case Choice of
  396.                 1: PromptOK(' Pretend ','Descriptions');
  397.                 2: ;
  398.                 3: PromptOK(' Pretend ','Self-Running Demo');
  399.                 4: PromptOK(' Pretend ','How to register');
  400.                 5: PromptOK(' About ','^Gold||Copyr.....');
  401.              end;
  402.           until Choice = 7;
  403.           MouseShow(false);
  404.           clrscr;
  405.  
  406.           Notice that the initial value of Choice is set before the menu
  407.      is first displayed, and that the repeat loop is terminated when the
  408.      user selects option 7 -- the quit option. Also, note that the code
  409.      includes a case statement after DisplayMenu to branch to another
  410.      part of the program based on the user's selection.
  411.  
  412.      That's all there is to it!
  413.  
  414. Created Nested Menus
  415.  
  416.           The following extract from DEMMEN5.PAS illustrates how to
  417.      create nested menus. In this example, when a user selects item 1
  418.      from the main menu, a sub-menu of additional items is displayed.
  419.      Pressing Esc in the sub-menu will return the user back to the main
  420.      menu.
  421.  
  422.           Choice := 1;
  423.           SubChoice := 1;
  424.           repeat
  425.              DisplayMenu(M1,false,Choice,ECode);
  426.              case Choice of
  427.                 1: begin
  428.                    repeat
  429.                       DisplayMenu(MM,true,SubChoice,ECode);
  430.                       if Ecode <> 0 then
  431.                          SubChoice := 5;
  432.                       case SubChoice of
  433.                         1: ;
  434.                         2: ;
  435.                         {etc.}
  436.                       end;
  437.                    until SubChoice = 5;
  438.                 end;
  439.                 2..4: PromptOK(' Selection ','You chose...       end;
  440.           until Choice = 5;
  441.           MouseShow(false);
  442.           clrscr;
  443.  
  444.           Notice there is a nested case statement to handle separately
  445.      the main and sub-menu choices, and that different variables are
  446.      used to track the menu selections: Choice and SubChoice.
  447.  
  448.